package com.yl.nettylearning.netty.rpc.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;

import static java.util.concurrent.Executors.*;

/**
 * @author yangl
 */
public class NettyClient {
    /**
     * 创建一个线程池
     */
    private static ExecutorService executor = newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    private static NettyClientHandler client;

    /**
     * 编写方法，使用代理模式，获得一个代理对象
     */
    public Object getBean(final Class<?> serviceClass, final String providerName){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class<?>[]{serviceClass},((proxy, method, args) -> {
                    //客户端每调用一次hello方法，就会进入该代码
            if(client == null){
                initClient();
            }
            //设置要发送给服务端的信息 providerName:协议头，args[0]:就是客户端调用api hello(??)
            client.setParam(providerName + args[0]);
            return executor.submit(client).get();
        }));
    }

    /**
     * 初始化client
     */
    public static void initClient(){
        client = new NettyClientHandler();
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group).channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(client);
                        }
                    });
            System.out.println("客户端启动，开始发送数据------");
            try {
                ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 7000).sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }finally {
            group.shutdownGracefully();
        }

    }
}
